package com.project.config;

import com.project.common.Security.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * SpringSecurity配置类
 *
 * @author Leo高洋
 * @create 2023-01-15 14:36
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //自定义登录成功处理
    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    //自定义登录失败处理
    @Autowired
    private LoginFailureHandler loginFailureHandler;

    //自定义登出成功处理
    @Autowired
    private JwtLogoutSuccessHandler jwtLogoutSuccessHandler;

    //JWT认证异常处理
    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    //SpringSecurity自定义UserDetails
    @Autowired
    private MyUserDetailsServiceImpl myUserDetailsService;

    //验证码过滤器
    @Autowired
    private CaptchaFilter captchaFilter;

    //请求白名单
    private static final String[] URL_WHITELIST = {
            "/login",
            "/logout",
            "/captcha",
            "/password",
            "/image/**",
            "/contract/**",
            "/asset/uploadContract",
            "/doc/**"
    };

    //请求认证过滤器
    @Bean
    JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JwtAuthenticationFilter(authenticationManager());
    }

    //加密（前段提交的密码）
    @Bean
    BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    //SpringSecurity基础配置重写
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                // 开启跨域 以及csrf攻击 关闭
                .cors()
                .and()
                .csrf()
                .disable()

                // 登录登出配置
                .formLogin()
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
                .and()
                .logout()
                .logoutSuccessHandler(jwtLogoutSuccessHandler)

                // session禁用配置，通过
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)  // 无状态

                // 拦截规则配置
                .and()
                .authorizeRequests()
                .antMatchers(URL_WHITELIST).permitAll()  // 白名单放行
                .anyRequest().authenticated()

                // 异常处理配置
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)

                // 自定义过滤器配置
                .and()
                .addFilter(jwtAuthenticationFilter())
                .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class);

    }
}